package com.cuvretool.view.draw;

import java.util.ArrayList;

import com.cuvretool.Base;
import com.cuvretool.View;
import com.cuvretool.model.detail.DrawString;
import com.cuvretool.utils.Vector2;
import com.cuvretool.view.coordinate.GridDrawInfo;
import com.cuvretool.view.coordinate.RulerDrawInfo;
import com.cuvretool.view.coordinate.Transform;
import com.cuvretool.view.coordinate.workspace.TransformWorkSpace;
/**
 * 提供基本绘制方法,点 线 多边形的绘制
 * @author boy
 */
public class DisplayDraw extends Transform implements Base {

	// ===========================================================
	// Constants
	// ===========================================================
	/**绘制无操作方式*/
	public final static int TYPE_NONE = 0;
	/**绘制点方式*/
	public final static int TYPE_POINTS = 1;
	/**绘制线方式*/
	public final static int TYPE_LINES = 2;
	/**绘制多边形方式*/
	public final static int TYPE_POLYGON = 3;
	// ===========================================================
	// Fields
	// ===========================================================
	/**左边和下边留出的区域*/
	@SuppressWarnings("unused")
	private float mGapX,mGapY;
	/**逻辑绘制的左下角坐标*/
	private int mBeginX,mBeginY;
	/**绘制方式*/
	private int mType;
	/**视图坐标,点集*/
	private ArrayList<Vector2> mPoints;
	/**视图坐标,线集*/
	private ArrayList<ArrayList<Vector2>> mLines;
	/**视图坐标,多边形集*/
	private ArrayList<ArrayList<Vector2>> mPolygon;
	/**视图坐标,字符串集*/
	private ArrayList<DrawString> mString;
	
	/**屏幕坐标,点集*/
	private ArrayList<Vector2> mSPoints;
	/**屏幕坐标,线集*/
	private ArrayList<ArrayList<Vector2>> mSLines;
	/**屏幕坐标,多边形集*/
	private ArrayList<ArrayList<Vector2>> mSPolygon;
	/**屏幕坐标,字符串集*/
	private ArrayList<DrawString> mSString;
	
	/**网格绘制需求参数结构定义*/
	private TransformWorkSpace mTransformWorkSpace;
	/**标尺绘制需求参数结构定义*/
	private RulerDrawInfo mRulerDrawInfo;
	
	/**全局定义*/
	private static DisplayDraw mDisplayDraw;
	// ===========================================================
	// Constructors
	// ===========================================================
	/**
	 * 单列
	 */
	private DisplayDraw(){
		init();
	}
	/**
	 * 获取各绘制方式的坐标
	 * @return
	 */
	public static DisplayDraw obtain(){
		if(mDisplayDraw == null){
			mDisplayDraw = new DisplayDraw();
			mDisplayDraw.mTransformWorkSpace = View.getViewInputHandleListener().mTransformWorkSpace;
			mDisplayDraw.mRulerDrawInfo = View.getViewInputHandleListener().mRulerDrawInfo;
		}
		mDisplayDraw.run();
		return mDisplayDraw;
	}
	// ===========================================================
	// Getter & Setter
	// ===========================================================
	/**
	 * 设置视图坐标,点集
	 * @param mPoints
	 */
	public void setPoints(ArrayList<Vector2> mPoints) {
		this.mPoints.clear();
		if(mPoints != null){
			this.mPoints.addAll(mPoints);
		}
	}
	/**
	 * 获取视图坐标,点集
	 * @return
	 */
	public ArrayList<Vector2> getPoints() {
		return mPoints;
	}
	/**
	 * 设置视图坐标,线集
	 * @param mLines
	 */
	public void setLines(ArrayList<ArrayList<Vector2>> mLines) {
		this.mLines.clear();
		if(mLines != null){
			this.mLines.addAll(mLines);
		}
	}
	/**
	 * 获取视图坐标,线集
	 * @return
	 */
	public ArrayList<ArrayList<Vector2>> getLines() {
		return mLines;
	}
	/**
	 * 设置视图坐标,多边形集
	 * @param mPolygon
	 */
	public void setPolygon(ArrayList<ArrayList<Vector2>> mPolygon) {
		this.mPolygon.clear();
		if(mPolygon != null){
			this.mPolygon.addAll(mPolygon);
		}
	}
	/**
	 * 获取视图坐标,多边形集
	 * @return
	 */
	public ArrayList<ArrayList<Vector2>> getPolygon() {
		return mPolygon;
	}
	/**
	 * 获取视图坐标,字符串集
	 */
	public ArrayList<DrawString> getString() {
		return mString;
	}
	/**
	 * 设置视图坐标,字符串集
	 * @param mSString
	 */
	public void setString(ArrayList<DrawString> mString) {
		this.mString.clear();
		if(mString != null){
			this.mString.addAll(mString);
		}
	}
	
	/**
	 * 设置屏幕坐标,点集
	 * @param mSPoints
	 */
	public void setSPoints(ArrayList<Vector2> mSPoints) {
		this.mSPoints.clear();
		if(mSPoints != null){
			this.mSPoints.addAll(mSPoints);
		}
	}
	/**
	 * 获取屏幕坐标,点集
	 * @return
	 */
	public ArrayList<Vector2> getSPoints() {
		return this.mSPoints;
	}
	/**
	 * 设置屏幕坐标,线集
	 * @param mSLines
	 */
	public void setSLines(ArrayList<ArrayList<Vector2>> mSLines) {
		this.mSLines.clear();
		if(mSLines != null){
			this.mSLines.addAll(mSLines);
		}
	}
	/**
	 * 获取屏幕坐标,线集
	 * @return
	 */
	public ArrayList<ArrayList<Vector2>> getSLines() {
		return this.mSLines;
	}
	/**
	 * 设置屏幕坐标,多边形集
	 * @param mSPolygon
	 */
	public void setSPolygon(ArrayList<ArrayList<Vector2>> mSPolygon) {
		this.mSPolygon.clear();
		if(mSPolygon != null){
			this.mSPolygon.addAll(mSPolygon);
		}
	}
	/**
	 * 获取屏幕坐标,多边形集
	 * @return
	 */
	public ArrayList<ArrayList<Vector2>> getSPolygon() {
		return this.mSPolygon;
	}
	/**
	 * 获取屏幕坐标,字符串集
	 */
	public ArrayList<DrawString> getSString() {
		return mSString;
	}
	/**
	 * 设置屏幕坐标,字符串集
	 * @param mSString
	 */
	public void setSString(ArrayList<DrawString> mSString) {
		this.mSString = mSString;
	}
	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================
	@Override
	public void init() {
		mPoints = new ArrayList<Vector2>();
		mLines = new ArrayList<ArrayList<Vector2>>();
		mPolygon = new ArrayList<ArrayList<Vector2>>();
		mString = new ArrayList<DrawString>();
		
		mSPoints = new ArrayList<Vector2>();
		mSLines = new ArrayList<ArrayList<Vector2>>();
		mSPolygon = new ArrayList<ArrayList<Vector2>>();
		mSString = new ArrayList<DrawString>();
		
		mType = TYPE_NONE;
	}
	
	/**
	 * 更新绘制区屏幕宽高和绘制区逻辑宽高
	 */
	@Override
	public void run() {
		GridDrawInfo gridDrawInfo = mTransformWorkSpace.getGridDrawInfo();
		mGapX = gridDrawInfo.mBeginX;
		mGapY = gridDrawInfo.mBeginY;
		Vector2 display = new Vector2(gridDrawInfo.getSpacingX(), gridDrawInfo.getSpacingY());
		setDisplaySize(display.x, display.y);
		Vector2 draw = new Vector2(mRulerDrawInfo.mSpacingX, mRulerDrawInfo.mSpacingY);
		setDrawSize(draw.x, draw.y);
		mBeginX = mRulerDrawInfo.mBeginX;
		mBeginY = mRulerDrawInfo.mBeginY;
	}
	
	/**
	 * 执行数组清理操作
	 */
	@Override
	public void over() {
		mPoints.clear();
		mLines.clear();
		for (int i = 0; i < mPolygon.size(); i++) {
			mPolygon.get(i).clear();
		}
		mPolygon.clear();
		mString.clear();
		
		mSPoints.clear();
		mSLines.clear();
		for (int i = 0; i < mSPolygon.size(); i++) {
			mSPolygon.get(i).clear();
		}
		mSPolygon.clear();
		mSString.clear();
	}
	/**
	 * 完成屏幕坐标转逻辑坐标
	 * @return
	 */
	@Override
	public boolean TransformDisplayToDraw() {
		float x,y;
		/*mSPoints*/
		mPoints.clear();
		for (int i = 0; i < mSPoints.size(); i++) {
			x = TransformDisplayToDrawX(mSPoints.get(i).x);
			y = TransformDisplayToDrawY(mSPoints.get(i).y);
			mPoints.add(new Vector2(x, y));
		}
		/*mString*/
		mString.clear();
		for (int i = 0; i < mSString.size(); i++) {
			x = TransformDisplayToDrawX(mSString.get(i).mPosition.x);
			y = TransformDisplayToDrawY(mSString.get(i).mPosition.y);
			DrawString drag = new DrawString();
			drag.mPosition = new Vector2(x, y);
			drag.mString = mSString.get(i).mString;
			mString.add(drag);
		}
		/*mSLines*/
		mLines.clear();
		for (int i = 0; i < mSLines.size(); i++) {
			ArrayList<Vector2> vec = mSLines.get(i);
			ArrayList<Vector2> result = new ArrayList<Vector2>();
			for (int n = 0; n < vec.size(); n++) {
				x = TransformDisplayToDrawX(vec.get(n).x);
				y = TransformDisplayToDrawY(vec.get(n).y);
				result.add(new Vector2(x, y));
			}
			mLines.add(result);
		}
		/*mSPolygon*/
		mPolygon.clear();
		for (int i = 0; i < mSPolygon.size(); i++) {
			ArrayList<Vector2> vec = mSPolygon.get(i);
			ArrayList<Vector2> result = new ArrayList<Vector2>();
			for (int n = 0; n < vec.size(); n++) {
				x = TransformDisplayToDrawX(vec.get(n).x);
				y = TransformDisplayToDrawY(vec.get(n).y);
				result.add(new Vector2(x, y));
			}
			mPolygon.add(result);
		}
		return true;
	}
	/**
	 * 完成逻辑坐标转屏幕坐标
	 * @return
	 */
	@Override
	public boolean TransformDrawToDisplay() {
		float x,y;
		/*mPoints*/
		mSPoints.clear();
		for (int i = 0; i < mPoints.size(); i++) {
			x = TransformDrawToDisplayX(mPoints.get(i).x);
			y = TransformDrawToDisplayY(mPoints.get(i).y);
			mSPoints.add(new Vector2(x, y));
		}
		/*mSString*/
		mSString.clear();
		for (int i = 0; i < mString.size(); i++) {
			x = TransformDrawToDisplayX(mString.get(i).mPosition.x);
			y = TransformDrawToDisplayY(mString.get(i).mPosition.y);
			DrawString drag = new DrawString();
			drag.mPosition = new Vector2(x, y);
			drag.mString = mString.get(i).mString;
			mSString.add(drag);
		}
		/*mLines*/
		mSLines.clear();
		for (int i = 0; i < mLines.size(); i++) {
			ArrayList<Vector2> vec = mLines.get(i);
			ArrayList<Vector2> result = new ArrayList<Vector2>();
			for (int n = 0; n < vec.size(); n++) {
				x = TransformDrawToDisplayX(vec.get(n).x);
				y = TransformDrawToDisplayY(vec.get(n).y);
				result.add(new Vector2(x, y));
			}
			mSLines.add(result);
		}
		/*mPolygon*/
		mSPolygon.clear();
		for (int i = 0; i < mPolygon.size(); i++) {
			ArrayList<Vector2> vec = mPolygon.get(i);
			ArrayList<Vector2> result = new ArrayList<Vector2>();
			for (int n = 0; n < vec.size(); n++) {
				x = TransformDrawToDisplayX(vec.get(n).x);
				y = TransformDrawToDisplayY(vec.get(n).y);
				result.add(new Vector2(x, y));
			}
			mSPolygon.add(result);
		}
		return true;
	}
	
	// ===========================================================
	// Methods
	// ===========================================================
	/**
	 * 设置绘制的内容
	 * @param vec
	 * @param type
	 */
	public void draw(ArrayList<Vector2> vec, int type){
		mType = type;
		if(mType == TYPE_POINTS){
			mPoints.addAll(vec);
		} else if (mType == TYPE_LINES) {
			mLines.add(vec);
		} else if (mType == TYPE_POLYGON) {
			mPolygon.add(vec);
		}
		mType = TYPE_NONE;
	}
	
	/**
	 * X坐标屏幕转逻辑
	 * @param x
	 * @return
	 */
	public float TransformDisplayToDrawX(float x) {
		float result = (x-mGapX) * mDrawWidth/mDisplayWidth + mBeginX;
		return result;
	}
	/**
	 * Y坐标屏幕转逻辑
	 * @param y
	 * @return
	 */
	public float TransformDisplayToDrawY(float y) {
		float height = mTransformWorkSpace.getGridDrawInfo().mTotalY;
		float result = (height-y) * mDrawHeight/mDisplayHeight + mBeginY;
		return result;
	}
	/**
	 * 坐标屏幕转逻辑
	 * @param pos
	 * @return
	 */
	public Vector2 TransformDisplayToDraw(Vector2 pos){
		Vector2 result = new Vector2();
		result.x = TransformDisplayToDrawX(pos.x);
		result.y = TransformDisplayToDrawY(pos.y);
		return result;
	}
	/**
	 * x距离屏幕转逻辑
	 * @param x
	 * @return
	 */
	public float TransformDisplayToDrawLenX(float x){
		return x*mDrawWidth/mDisplayWidth;
	}
	/**
	 * x距离屏幕转逻辑
	 * @param x
	 * @return
	 */
	public float TransformDisplayToDrawLenY(float y){
		return y*mDrawHeight/mDisplayHeight;
	}
	public Vector2 TransformDisplayToDrawLen(Vector2 pos){
		Vector2 result = new Vector2();
		result.x = TransformDisplayToDrawLenX(pos.x);
		result.y = TransformDisplayToDrawLenY(pos.y);
		return result;
	}
	/**
	 * X坐标逻辑转屏幕
	 * @param x
	 * @return
	 */
	public float TransformDrawToDisplayX(float x) {
		float result = (x-mBeginX) * mDisplayWidth/mDrawWidth + mGapX;
		return result;
	}
	/**
	 * Y坐标逻辑转屏幕
	 * @param x
	 * @return
	 */
	public float TransformDrawToDisplayY(float y) {
		float height = mTransformWorkSpace.getGridDrawInfo().mTotalY;
		float result = height - (y-mBeginY) * mDisplayHeight/mDrawHeight;
		return result;
	}
	/**
	 * 坐标逻辑转屏幕
	 * @param pos
	 * @return
	 */
	public Vector2 TransformDrawToDisplay(Vector2 pos){
		Vector2 result = new Vector2();
		result.x = TransformDrawToDisplayX(pos.x);
		result.y = TransformDrawToDisplayY(pos.y);
		return result;
	}
	/**
	 * x距离逻辑转屏幕
	 * @param x
	 * @return
	 */
	public float TransformDrawToDisplayLenX(float x){
		return x*mDisplayWidth/mDrawWidth;
	}
	/**
	 * y距离逻辑转屏幕
	 * @param y
	 * @return
	 */
	public float TransformDrawToDisplayLenY(float y){
		return y*mDisplayHeight/mDrawHeight;
	}
	/**
	 * 逻辑距离转屏幕
	 * @param pos
	 * @return
	 */
	public Vector2 TransformDrawToDisplayLen(Vector2 pos){
		Vector2 result = new Vector2();
		result.x = TransformDrawToDisplayLenX(pos.x);
		result.y = TransformDrawToDisplayLenX(pos.y);
		return result;
	}
	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}
